import string
import wx
import os
from wx import xrc
from script import config
from script import View
from script import release

SCRIPT_HOME = r".\script"
CONFIG_XML_FILE = r".\script\config.xml"

FILTER_TYPE=1
FILTER_DIGIT=2
FILTER_PART_NO=3
class CVerValidator(wx.PyValidator):
    def __init__(self, flag=None):
        wx.PyValidator.__init__(self)
        self.Bind(wx.EVT_CHAR, self.OnChar)
        self.typeList = ['R','I','D','r','i','d']

        self.flag=flag

    def Clone(self):
        return CVerValidator(self.flag)

    def OnChar(self, event):
        key = event.GetKeyCode()

        if key == wx.WXK_BACK or key == wx.WXK_DELETE:
            event.Skip()
            return

        if self.flag == FILTER_TYPE:
            if chr(key) not in self.typeList:
                return
            else:
                self.GetWindow().SetValue(chr(key).upper())
                return
        elif self.flag == FILTER_DIGIT:
            if chr(key) not in string.digits:
                return
        elif self.flag == FILTER_PART_NO:
            self.GetWindow().AppendText(chr(key).upper())
            return

        event.Skip()
        return

class MyApp(wx.App):
    def OnInit(self):
        self.res = xrc.XmlResource('ReleaseGUI.xrc')
        self.InitFrame()

        self.cfg = config.CConfig()
        return True

    def InitFrame(self):
        self.frame = self.res.LoadFrame(None, 'frame_release')
        self.panel = xrc.XRCCTRL(self.frame, 'panel_release')

        self.pathCtrl = xrc.XRCCTRL(self.panel, 'tc_view_path')
        self.rbCarType = xrc.XRCCTRL(self.panel, 'rb_car_type')
        self.InitS12VerCtrl()
        self.InitVerCtrl()
        self.InitCheckBox()

        self.BindEvent()
        self.frame.Show()


    #this function change the s12 version prefix and suffix value
    def SetS12VerUnchangeValue(self):
        carStr = self.rbCarType.GetStringSelection()
        self.tcS12VerPre.SetValue("NISSAN_%s_DCM" % carStr)
        if carStr == "INFINITI":
            self.stS12Sep.Show(False)
            self.tcS12VerSur.Show(False)
        else:
            self.stS12Sep.Show(True)
            self.tcS12VerSur.Show(True)


    def InitS12VerCtrl(self):
        self.tcS12VerPre = xrc.XRCCTRL(self.panel, 'tc_s12_ver_pre')
        self.tcS12VerId = xrc.XRCCTRL(self.panel, 'tc_s12_ver_id')

        self.tcS12VerSur = xrc.XRCCTRL(self.panel, 'tc_s12_ver_suf')
        self.stS12Sep = xrc.XRCCTRL(self.panel, 'st_s12_sep')
        #print self.stS12Sep

        self.SetS12VerUnchangeValue()



    def InitVerCtrl(self):
        self.tcVerHigh = xrc.XRCCTRL(self.panel, 'tc_ver_high')
        self.tcVerHigh.SetValidator(CVerValidator(FILTER_DIGIT))

        self.tcVerLow = xrc.XRCCTRL(self.panel, 'tc_ver_low')
        self.tcVerLow.SetValidator(CVerValidator(FILTER_DIGIT))

        self.tcVerType = xrc.XRCCTRL(self.panel, 'tc_ver_type')
        self.tcVerType.SetValidator(CVerValidator(FILTER_TYPE))

        self.tcSvn1 = xrc.XRCCTRL(self.panel, 'tc_svn_1')
        self.tcSvn1.SetValidator(CVerValidator(FILTER_DIGIT))

        self.tcSvn2 = xrc.XRCCTRL(self.panel, 'tc_svn_2')
        self.tcSvn2.SetValidator(CVerValidator(FILTER_DIGIT))

        #this check box only for part no, don't add to the list
        self.cbPartNo = xrc.XRCCTRL(self.panel, 'cb_part_no')
        self.tcPartNo = xrc.XRCCTRL(self.panel, 'tc_part_no')
        self.tcPartNo.SetValidator(CVerValidator(FILTER_PART_NO))
    def InitCheckBox(self):
        #cb list, this list does not include release check box
        self.cbList = []

        #add the check box into a list, which is only for action check box
        self.cbRelease = xrc.XRCCTRL(self.panel, 'cb_release')


        self.cbUpdateView = xrc.XRCCTRL(self.panel, 'cb_update_view')
        self.cbUpdateView.SetWindowStyle(wx.CHK_3STATE)
        self.cbList.append(self.cbUpdateView)

        self.cbUpdateVF = xrc.XRCCTRL(self.panel, 'cb_update_vf')
        self.cbUpdateVF.SetWindowStyle(wx.CHK_3STATE)
        self.cbList.append(self.cbUpdateVF)

        self.cbGenerate = xrc.XRCCTRL(self.panel, 'cb_generate_code')
        self.cbGenerate.SetWindowStyle(wx.CHK_3STATE)
        self.cbList.append(self.cbGenerate)

        self.cbCompile = xrc.XRCCTRL(self.panel, 'cb_compile')
        self.cbCompile.SetWindowStyle(wx.CHK_3STATE)
        self.cbList.append(self.cbCompile)

        self.cbSave = xrc.XRCCTRL(self.panel, 'cb_save')
        self.cbSave.SetWindowStyle(wx.CHK_3STATE)
        self.cbList.append(self.cbSave)




    def BindEvent(self):
        frame = self.frame
        frame.Bind(wx.EVT_BUTTON, self.OnButtonRun, id=xrc.XRCID('btn_run'))
        frame.Bind(wx.EVT_BUTTON, self.OnExit, id=xrc.XRCID('btn_exit'))
        frame.Bind(wx.EVT_MENU, self.OnMenuExit, id=xrc.XRCID('menu_item_exit'))

        frame.Bind(wx.EVT_CHECKBOX, self.OnChkRelease, id=xrc.XRCID('cb_release'))
        for cb in self.cbList:
            frame.Bind(wx.EVT_CHECKBOX, self.OnChkAction, cb)

        frame.Bind(wx.EVT_BUTTON, self.OnButtonBrowse, id=xrc.XRCID('btn_browse'))
        frame.Bind(wx.EVT_RADIOBOX, self.OnRbCarType, id=xrc.XRCID('rb_car_type'))
        frame.Bind(wx.EVT_CHECKBOX, self.OnChkPartNo, id=xrc.XRCID('cb_part_no'))

    def OnChkPartNo(self, event):
        if event.IsChecked():
            self.tcPartNo.Enable()
        else:
            self.tcPartNo.Disable()
            self.tcPartNo.SetValue('')

    def OnRbCarType(self, event):
        self.SetS12VerUnchangeValue()

    def OnButtonBrowse(self, event):
        dlg = wx.DirDialog(self.frame, "Choose View Directory:",
                          style=wx.DD_DEFAULT_STYLE
                           #| wx.DD_DIR_MUST_EXIST
                           #| wx.DD_CHANGE_DIR
                           )
        if dlg.ShowModal() == wx.ID_OK:
            self.pathCtrl.SetValue(dlg.GetPath())

    #get the information of the selection from GUI
    def GetInformation(self):
        self.cfg.type = self.rbCarType.GetStringSelection()

        if self.cbRelease.IsChecked():
            self.cfg.selection.All = "Y"
        else:
            self.cfg.selection.All = "N"

        if self.cbUpdateView.Get3StateValue() != wx.CHK_UNCHECKED:
            self.cfg.selection.UpdateView = "Y"
        else:
            self.cfg.selection.UpdateView = "N"

        if self.cbUpdateVF.Get3StateValue() != wx.CHK_UNCHECKED:
            self.cfg.selection.UpdateVF = "Y"
        else:
            self.cfg.selection.UpdateVF = "N"

        if self.cbGenerate.Get3StateValue() != wx.CHK_UNCHECKED:
            self.cfg.selection.Generate = "Y"
        else:
            self.cfg.selection.Generate = "N"

        if self.cbCompile.Get3StateValue() != wx.CHK_UNCHECKED:
            self.cfg.selection.Compile = "Y"
        else:
            self.cfg.selection.Compile = "N"

        if self.cbSave.Get3StateValue() != wx.CHK_UNCHECKED:
            self.cfg.selection.Save = "Y"
        else:
            self.cfg.selection.Save = "N"

        self.cfg.sgold_ver_high = self.tcVerHigh.GetValue()
        self.cfg.sgold_ver_low = self.tcVerLow.GetValue()
        self.cfg.sgold_ver_type = self.tcVerType.GetValue()
        self.cfg.sgold_ver_svn = r"00.00:%s.%s:06.01" % (self.tcSvn1.GetValue(), self.tcSvn2.GetValue())
        self.cfg.s12_ver_id = self.tcS12VerId.GetValue()

        self.cfg.viewHome = self.pathCtrl.GetValue()
        self.cfg.partNo = self.tcPartNo.GetValue()

    #display dialog to confirm the information
    def ConfirmInformation(self):
        self.confirmDialog = self.res.LoadDialog(None, 'dialog_confirm')
        st_sgold_version = xrc.XRCCTRL(self.confirmDialog, 'st_sgold_version')
        st_sgold_version.SetLabel("%s.%s%s" % (self.cfg.sgold_ver_high, self.cfg.sgold_ver_low, self.cfg.sgold_ver_type))

        st_sgold_svn = xrc.XRCCTRL(self.confirmDialog, 'st_sgold_svn')
        st_sgold_svn.SetLabel("%s" % self.cfg.sgold_ver_svn)

        st_s12_version = xrc.XRCCTRL(self.confirmDialog, 'st_s12_version')
        pre = self.tcS12VerPre.GetValue()
        sur = self.tcS12VerSur.GetValue()
        st_s12_version.SetLabel("%s_%s_%s" % (pre,self.cfg.s12_ver_id, sur))


        st_part_no =  xrc.XRCCTRL(self.confirmDialog, 'st_part_no')
        st_part_no.SetLabel("%s" % self.cfg.partNo)

        st_view_home =  xrc.XRCCTRL(self.confirmDialog, 'st_view_home')
        st_view_home.SetLabel("%s" % self.cfg.viewHome)

        #as create view instance would change the dir to the view home
        preCwd = os.getcwd()
        view = View.CDcmView(self.cfg.viewHome)
        os.chdir(preCwd)
        view.SetConfig(self.cfg)
        releaseDir = view.GetReleaseDir()
        releaseDir = os.path.join(self.cfg.viewHome, releaseDir)
        st_release_dir =  xrc.XRCCTRL(self.confirmDialog, 'tc_release_dir')
        st_release_dir.SetValue("%s" % releaseDir)

        val = self.confirmDialog.ShowModal()

        if val == wx.ID_OK:
            self.cfg.UpdateToFile(CONFIG_XML_FILE)
            self.RunReleaseScript()

        self.confirmDialog.Destroy()


    #check if all information has been filled
    def CheckBlank(self):
        if self.cfg.sgold_ver_high == '' or \
                self.cfg.sgold_ver_low == '' or \
                self.cfg.sgold_ver_type == '' or \
                self.cfg.sgold_ver_svn == '' or \
                self.cfg.s12_ver_id == '' or \
                self.cfg.viewHome == '':
            self.warnDialog = self.res.LoadDialog(None, 'dialog_warning')
            self.warnDialog.ShowModal()
            self.warnDialog.Destroy()
            return False
        else:
            return True

    def RunReleaseScript(self):
        rel = release.CRlease(SCRIPT_HOME)
        rel.run()


    def OnButtonRun(self, event):
        self.GetInformation()
        if self.CheckBlank():
            self.ConfirmInformation()


    def OnExit(self, event):
        self.frame.Close(True)

    def OnMenuExit(self, event):
        self.frame.Close(True)

    def OnChkAction(self, event):
        if event.IsChecked() == False:
            self.cbRelease.SetValue(False)

        for cb in self.cbList:
            if cb.Get3StateValue() != wx.CHK_UNCHECKED:
                cb.Set3StateValue(wx.CHK_CHECKED)

    def OnChkRelease(self, event):
        if event.IsChecked():
            value = wx.CHK_UNDETERMINED
        else:
            value = wx.CHK_UNCHECKED


        for cb in self.cbList:
            cb.Set3StateValue(value)


if __name__ == '__main__':
    app = MyApp(False)
    app.MainLoop()
